package com.liu.analysis;


import java.util.ArrayList;
import java.util.List;

import com.liu.system.Error;
import com.liu.system.MyException;
import com.liu.system.Symbol;

/*
 * 词法分析类
 * 创建于2017.3.8
 * @author lyq
 * */
public class WordAnalysis {
	
	/* 变量名寄存字段，可临时寄存一个变量名 */
	private static StringBuffer variableRegister = new StringBuffer();

	/* 数字寄存字段，可临时寄存一个数字 */
	private static StringBuffer digitRegister = new StringBuffer();

	/* 是否存储有空白符 */
	private static boolean anySpace = false;

	/*
	 * 判断是否是字母
	 * @param ch 需要判断的字符
	 * @return true代表是字母，false代表不是字母
	 */
	private static boolean isLetter(char ch) {
		if ((ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122)) {
			return true;
		}
		return false;
	}

	/*
	 * 判断是否是数字
	 * @param ch 需要判断的字符
	 * @return true代表是数字，false代表不是数字
	 */
	private static boolean isDigit(char ch) {
		if (ch >= 48 && ch <= 57) {
			return true;
		}
		return false;
	}

	/*
	 * 判断是否是空格或换行
	 * @param ch 需要判断的字符 
	 * @return true代表是空白符，false代表不是
	 */
	private static boolean isSpace(char ch) {
		if (ch == 32 || ch == 10) {
			return true;
		}
		return false;
	}

	/*
	 * 判断是否是小数点
	 * @param ch 需要判断的字符
	 * @return true代表是小数点，false代表不是
	 */
	private static boolean isPoint(char ch) {
		if (ch == 46) {
			return true;
		}
		return false;
	}

	/*
	 * 判断是否是系统符号
	 * @param ch 需要判断的字符
	 * @return true代表是系统符号，false代表不是
	 */
	private static boolean isSymbol(char ch) {
		for (char symbol : Symbol.symbols) {
			if (symbol == ch) {
				return true;
			}
		}
		return false;
	}

	
	/*
	 * 对一段输入的字符串进行词法分析
	 * @param str 需要分析的字符串
	 * @return 返回经过词法分析后的字符串队列
	 * @exception 数字前有空白符时出现异常
	 */
	public static List<String> wordAnalysis(String str) throws MyException {
		//用来存放分析结果
		List<String> result = new ArrayList<String>();
		
		for (int i = 0; i < str.length(); i++) {
			char ch = str.charAt(i);
			// 是字母
			if (isLetter(ch)) {
				if (!variableRegister.toString().equals("")) {
					// 字母-空白符-字母
					if (anySpace) {
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.LETTER_SPACE_LETTER);
					}
					// 字母-字母
					else {
						variableRegister.append(ch);
						continue;
					}
				}
				if (!digitRegister.toString().equals("")) {
					// 数字-空白符-字母
					if (anySpace) {
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.NUMBER_SPACE_LETTER);
					}
					// 数字-字母
					else {
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.LETTER_AFTER_NUMBER);
					}
				}
				variableRegister.append(ch);
				anySpace = false;
				continue;
			}
			// 是数字
			if (isDigit(ch)) {
				if (!variableRegister.toString().equals("")) {
					// 字母-空白符-数字
					if (anySpace) {
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.LETTER_SPACE_NUMBER);
					}
					// 字母-数字
					else {
						variableRegister.append(ch);
						continue;
					}
				}
				if (!digitRegister.toString().equals("")) {
					// 数字-空白符-数字
					if (anySpace) {
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.NUMBER_SPACE_NUMBER);
					}
					// 数字-数字
					else {
						digitRegister.append(ch);
						continue;
					}
				}
				digitRegister.append(ch);
				anySpace = false;
				continue;
			}
			// 是空白符，记录出现了空格符，然后继续循环
			if (isSpace(ch)) {
				anySpace = true;
				continue;
			}
			//是小数点
			if(isPoint(ch)){
				if(anySpace){
					variableRegister.setLength(0);
					digitRegister.setLength(0);
					throw new MyException(Error.POINT_AFTER_SPACE);
				}
				else{
					if(!variableRegister.toString().equals("")){
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.POINT_AFTER_LETTER);
					}
					if(!digitRegister.toString().equals("")){
						if(digitRegister.toString().contains(String.valueOf(Symbol.point))){
							variableRegister.setLength(0);
							digitRegister.setLength(0);
							throw new MyException(Error.POINT_AFTER_POINT);
						}
						digitRegister.append(ch);
						continue;
					}
				}
			}
			//是系统符号
			if(isSymbol(ch)){
				anySpace = false;
				//变量寄存器中存有变量
				if(!variableRegister.toString().equals("")){
					result.add(variableRegister.toString());
					//清空变量寄存器
					variableRegister.setLength(0);
				}
				//数字寄存器中存有数字
				if(!digitRegister.toString().equals("")){
					if(digitRegister.toString().endsWith(String.valueOf(Symbol.point))){
						variableRegister.setLength(0);
						digitRegister.setLength(0);
						throw new MyException(Error.NUMBER_END_POINT);
					}
					result.add(digitRegister.toString());
					//清空变量寄存器
					digitRegister.setLength(0);
				}
				result.add(String.valueOf(ch));
				continue;
			}
			variableRegister.setLength(0);
			digitRegister.setLength(0);
			throw new MyException(Error.CONTAIN_UNKNOWN_CAHR);
		}
		//变量寄存器中存有变量
		if(!variableRegister.toString().equals("")){
			result.add(variableRegister.toString());
			//清空变量寄存器
			variableRegister.setLength(0);
		}
		//数字寄存器中存有数字
		if(!digitRegister.toString().equals("")){
			if(digitRegister.toString().endsWith(String.valueOf(Symbol.point))){
				variableRegister.setLength(0);
				digitRegister.setLength(0);
				throw new MyException(Error.NUMBER_END_POINT);		
			}
			result.add(digitRegister.toString());
			digitRegister.setLength(0);
		}
		return result;
	}
}
